<?php
/**
 *
 * @createTime: 2016-07-14 17:42
 * @description: 暴露给客户端调用的接口
 * @link      https://github.com/helei112g/payment/tree/paymentv2
 * @link      https://helei112g.github.io/
 */

namespace Payment;

use Payment\Charge\Ali\AliAppCharge;
use Payment\Charge\Ali\AliBarCharge;
use Payment\Charge\Ali\AliWapCharge;
use Payment\Charge\Ali\AliWebCharge;
use Payment\Charge\Ali\AliQrCharge;
use Payment\Charge\Cmb\CmbCharge;
use Payment\Charge\Fu\FuBarCharge;
use Payment\Charge\Fu\FuPubCharge;
use Payment\Charge\Fu\FuScanCharge;
use Payment\Charge\LTF\LTFBarCharge;
use Payment\Charge\LTF\LTFLiteCharge;
use Payment\Charge\LTF\LTFPayCharge;
use Payment\Charge\LTF\LTFPubCharge;
use Payment\Charge\LTF\LTFScanCharge;
use Payment\Charge\MiPay\MiLiteCharge;
use Payment\Charge\Sw\SwBarCharge;
use Payment\Charge\Sw\SwFaceCharge;
use Payment\Charge\Sw\SwFaceInfo;
use Payment\Charge\Sw\SwLiteCharge;
use Payment\Charge\SwThree\SwLiteThreeCharge;
use Payment\Charge\SwThree\SwPubThreeCharge;
use Payment\Charge\SwThree\SwScanThreeCharge;
use Payment\Charge\SwThree\SwBarThreeCharge;
use Payment\Charge\Sw\SwPubCharge;
use Payment\Charge\Sw\SwScanCharge;
use Payment\Charge\TLpay\TLLiteCharge;
use Payment\Charge\Wx\WxAppCharge;
use Payment\Charge\Wx\WxBarCharge;
use Payment\Charge\Wx\WxPubCharge;
use Payment\Charge\Wx\WxQrCharge;
use Payment\Charge\Wx\WxWapCharge;
use Payment\Charge\YS\YSNatCharge;
use Payment\Charge\YS\YSPubCharge;
use Payment\Charge\YS\YSScanCharge;
use Payment\Charge\WNFPay\WNFCharge;

use Payment\Charge\YSE\YSEPubCharge;

use Payment\Charge\Hsq\HsqPubCharge;

use Payment\Common\BaseStrategy;
use Payment\Common\PayException;

/**
 * Class ChargeContext
 *
 * 支付的上下文类
 *
 * @package Payment
 *
 */
class ChargeContext
{
    /**
     * 支付的渠道
     * @var BaseStrategy
     */
    protected $channel;


    /**
     * 设置对应的支付渠道
     * @param string $channel 支付渠道
     *  - @see Config
     * @param array $config 配置文件
     * @throws PayException
     */
    public function initCharge($channel, array $config)
    {
        // 初始化时，可能抛出异常，再次统一再抛出给客户端进行处理
        try {
            switch ($channel) {
                //支付宝
                case Config::ALI_CHANNEL_WAP:
                    $this->channel = new AliWapCharge($config);
                    break;
                case Config::ALI_CHANNEL_APP:
                    $this->channel = new AliAppCharge($config);
                    break;
                case Config::ALI_CHANNEL_WEB:
                    $this->channel = new AliWebCharge($config);
                    break;
                case Config::ALI_CHANNEL_QR:
                    $this->channel = new AliQrCharge($config);
                    break;
                case Config::ALI_CHANNEL_BAR:
                    $this->channel = new AliBarCharge($config);
                    break;

                //微信
                case Config::WX_CHANNEL_APP:
                    $this->channel = new WxAppCharge($config);
                    break;
                case Config::WX_CHANNEL_LITE:// 小程序支付与公众号支付一样，仅仅是客户端的调用方式不同
                case Config::WX_CHANNEL_PUB:
                    $this->channel = new WxPubCharge($config);
                    break;
                case Config::WX_CHANNEL_WAP:
                    $this->channel = new WxWapCharge($config);
                    break;
                case Config::WX_CHANNEL_QR:
                    $this->channel = new WxQrCharge($config);
                    break;
                case Config::WX_CHANNEL_BAR:
                    $this->channel = new WxBarCharge($config);
                    break;
                case Config::CMB_CHANNEL_WAP:
                case Config::CMB_CHANNEL_APP:
                    $this->channel = new CmbCharge($config);
                    break;

                //通联
                case Config::TL_CHANNEL_LITE: //通联支付
                    $this->channel = new TLLiteCharge($config);
                    break;

                //米付
                case Config::MI_CHANNEL_LITE: //米付小程序通道
                    $this->channel = new MiLiteCharge($config);
                    break;

                //扫呗
                case Config::SW_CHANNEL_PUB:
                    $this->channel = new SwPubCharge($config);
                    break;
                case Config::SW_CHANNEL_LITE:
                    $this->channel = new SwLiteCharge($config);
                    break;
                case Config::SW_CHANNEL_SCAN: //目前主扫模式已经逐步被被扫模式替换
                    $this->channel = new SwScanCharge($config);
                    break;
                case Config::SW_CHANNEL_BAR: //用户被扫模式
                    $this->channel = new SwBarCharge($config);
                    break;
                case Config::SW_CHANNEL_FACEPAY:
                    $this->channel = new SwFaceCharge($config);
                    break;
                case Config::SW_CHANNEL_FACEPAY_TOKEN:
                    $this->channel = new SwFaceInfo($config);
                    break;

                //扫呗(3.0)
                case Config::SW_T_CHANNEL_PUB:
                    $this->channel = new SwPubThreeCharge($config);
                    break;
                case Config::SW_T_CHANNEL_LITE:
                    $this->channel = new SwLiteThreeCharge($config);
                    break;
                case Config::SW_T_CHANNEL_SCAN: //目前主扫模式已经逐步被被扫模式替换
                    $this->channel = new SwScanThreeCharge($config);
                    break;
                case Config::SW_T_CHANNEL_BAR: //用户被扫模式
                    $this->channel = new SwBarThreeCharge($config);
                    break;
//                case Config::SW_CHANNEL_FACEPAY:
//                    $this->channel = new SwFaceCharge($config);
//                    break;
//                case Config::SW_CHANNEL_FACEPAY_TOKEN:
//                    $this->channel = new SwFaceInfo($config);
//                    break;

                //富友
                case Config::FU_CHANNEL_PUB:
                case Config::FU_CHANNEL_LITE:
                    $this->channel = new FuPubCharge($config);
                    break;
                case Config::FU_CHANNEL_SCAN:
                    $this->channel = new FuScanCharge($config);
                    break;
                case Config::FU_CHANNEL_BAR:
                    $this->channel = new FuBarCharge($config);
                    break;

                //联拓富
				case Config::LTF_CHANNEL_PUB:
					$this->channel = new LTFPubCharge($config);
					break;
				case Config::LTF_CHANNEL_LITE:
					$this->channel = new LTFLiteCharge($config);
					break;
				case Config::LTF_CHANNEL_SCAN:
					$this->channel = new LTFScanCharge($config);
					break;
				case Config::LTF_CHANNEL_BAR:
					$this->channel= new LTFBarCharge($config);
					break;
				case Config::LTF_CHANNEL_PAY:
					$this->channel=new LTFPayCharge($config);
					break;

                //易生支付
                case Config::YS_CHANNEL_PUB:
                case Config::YS_CHANNEL_LITE:  //小程序、公众号
                    $this->channel = new YSPubCharge($config);
                    break;
                case Config::YS_CHANNEL_SCAN:   //被扫
                    $this->channel = new YSScanCharge($config);
                    break;
                case Config::YS_CHANNEL_NATIVE:  //主扫
                    $this->channel = new YSNatCharge($config);
                    break;

                case Config::YSE_CHANNEL_PUB:
                case Config::YSE_CHANNEL_LITE:  //小程序、公众号
                    $this->channel = new YSEPubCharge($config);
                    break;
                case Config::WNF_WECHAT_LITE:
                case Config::WNF_ALI_APP:
                    $this->channel = new WNFCharge($config);
                    break;

                //慧收钱
                case Config::HSQ_CHANNEL_LITE:
                    $this->channel = new HsqPubCharge($config);
                    break;


                default:
                    throw new PayException('当前支持：支付宝、微信、招商一网通、通联支付、米付支付、扫呗支付、富友支付、联拓富、易生支付、微诺付、慧收钱。');
            }
        } catch (PayException $e) {
            throw $e;
        }
    }

    /**
     * 通过环境类调用支付
     * @param array $data
     *
     * ```php
     * $payData = [
     *      "order_no" => createPayid(),
     *      "amount" => '0.01',// 单位为元 ,最小为0.01
     *      "client_ip" => '127.0.0.1',
     *      "subject" => '测试支付',
     *      "body" => '支付接口测试',
     *      "extra_param"   => '',
     * ];
     * ```
     *
     * @return array
     * @throws PayException
     *
     */
    public function charge(array $data)
    {
        if (!$this->channel instanceof BaseStrategy) {
            throw new PayException('请检查初始化是否正确');
        }

        try {
            return $this->channel->handle($data);
        } catch (PayException $e) {
            throw $e;
        }
    }
}
